#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

template<typename T=int, size_t sz=10>
class Queue{
public:
    Queue();
    ~Queue();
    bool empty() const;
    bool full() const;
    void push(const T &value);
    void pop();
    T front();
    T back();

private:
    int _front;
    int _rear;
    T *_pdata;
};

template<typename T,size_t sz>
Queue<T,sz>::Queue()
: _front(0)
, _rear(0)
, _pdata(new T[sz]())
{
    cout<<"Queue()"<<endl;
}

template<typename T,size_t sz>
Queue<T,sz>::~Queue(){
    cout<<"~Queue()"<<endl;
    if(_pdata){
        delete [] _pdata;
        _pdata=nullptr;
    }
}

template<typename T,size_t sz>
bool Queue<T,sz>::empty() const {
    return _front==_rear;
}

template<typename T,size_t sz>
bool Queue<T,sz>::full() const{
    return (_front == (_rear + 1) % sz);
}

template<typename T,size_t sz>
void Queue<T,sz>::push(const T &value){
    if(!full()){
        _pdata[_rear++] = value;
        _rear = _rear % sz;
    }
    else{
        cout<<"The queue is full"<<endl;
        return;
    }
}

template<typename T,size_t sz>
void Queue<T,sz>::pop(){
    if(!empty()){
        ++ _front;
        _front = _front % sz;
    }
    else{
        cout<<"The queue is empty"<<endl;
        return;
    }
}

template<typename T,size_t sz>
T Queue<T,sz>::front(){
    return _pdata[_front];
}

template<typename T,size_t sz>
T Queue<T,sz>::back(){
    return _pdata[(_rear -1 + sz) % sz];
}

void test(){
    Queue<int,20> qu;
    cout<<qu.empty()<<endl;
    qu.push(1);
    cout<<qu.full()<<endl;

    for(size_t idx=2; idx!=12; ++idx){
        qu.push(idx);
    }
    cout<<"队列满了吗？"<<qu.full()<<endl;

    while(!qu.empty()){
        cout<<qu.front()<<" ";
        qu.pop();
    }

    cout<<endl;
    cout<<"队列空了吗？"<<qu.empty()<<endl;
}

void test2(){
    Queue<string,13> qu;
    cout<<qu.empty()<<endl;
    qu.push(string("aa"));
    cout<<qu.full()<<endl;

    for(size_t idx=1; idx!=15; ++idx){
        qu.push(string(2,'a'+idx));     //这是string的一个构造函数，2是叠词
    }
    cout<<"队列满了吗？"<<qu.full()<<endl;
    
    while(!qu.empty()){
        cout<<qu.front()<<" ";
        qu.pop();
    }

    cout<<endl;
    cout<<"队列空了吗？"<<qu.empty()<<endl;
}

int main()
{   
    test2();
    return 0;
}

